package find.prj.lib;

public class TurboList<T> extends MegaList<T> {
	
	public TurboNode<T> LastNode;
	
	public TurboList() {
		super();
		this.LastNode = null;
	}
	
	public TurboList(T value) {
		super(value);
		this.LastNode = (TurboNode<T>) this.FirstNode;
	}
	
	public TurboList(T[] valueArray) {
		super(valueArray);
	}
	
	@Override
	protected TurboNode<T> getListNode (int index) {
		if ((index < this.Size) && (index >= 0)) {
			if (index <=  Size/2) {
				TurboNode<T> node = (TurboNode<T>) this.FirstNode;
				for (int k=0; ; k++) {
					if (k == index)
						return node;
					node = (TurboNode<T>) node.NextNode;
				}
			}
			else {
				TurboNode<T> node = this.LastNode; 
				for (int k =  Size-1 ; ; k--) {
					if (k == index)
						return node;
					node = node.PreviousNode;
				}				
			}
		}
		else
			throw new IndexOutOfBoundsException();		
	}
	
	@Override
	public boolean add(T value) {
		TurboNode<T> newNode = new TurboNode<T>(value);
		if (this.isEmpty())
			this.FirstNode = (ListNode<T>) newNode;
		else {
			newNode.PreviousNode = this.LastNode;
			this.LastNode.NextNode = (TurboNode<T>) newNode;
		}
		this.LastNode = newNode;
		this.Size++;
		return true;
	}

	@Override
	public void clear() {
		super.clear();
		this.LastNode = null;
	}

	@Override
	public void removeIndex(int index) {
		if ( (index < this.Size) && (index >= 0) && (this.Size > 0) ) {
			if (this.Size == 1)
				this.FirstNode = this.LastNode = null;
			else {
				if (index == 0) {
					this.FirstNode = this.FirstNode.NextNode;
					this.getListNode(0).PreviousNode = null;
				}
				else
					if (index == Size-1) {
						this.LastNode = this.LastNode.PreviousNode;
						this.LastNode.NextNode = null;
					}
					else {
						TurboNode<T> deleteNode = this.getListNode(index);
						TurboNode<T> nextNode = (TurboNode<T>) deleteNode.NextNode;
						TurboNode<T> previousNode = deleteNode.PreviousNode;
						previousNode.NextNode = nextNode;
						nextNode.PreviousNode = previousNode;
					}
			}
			this.Size--;
		}
		else
			throw new IndexOutOfBoundsException(); 
	}
}
